package com.fitns.user.service.organ;


import com.fitns.user.constant.Constants;
import com.fitns.user.dao.organ.CompanyDao;
import com.fitns.user.dao.organ.OrganDao;
import com.fitns.user.dto.organ.OrganTree;
import com.fitns.user.dto.organ.OrganVO;
import com.fitns.user.dto.user.PrivilegeVO;
import com.fitns.user.exception.OrganMsgCode;
import com.fitns.user.exception.ServiceException;
import com.fitns.user.model.organ.Company;
import com.fitns.user.model.organ.Organ;
import com.fitns.user.service.user.UserService;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.xiaoleilu.hutool.lang.Validator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrganService {

    @Autowired
    private OrganDao organDao;

    @Autowired
    private CompanyDao companyDao;

    @Autowired
    private UserService userService;


    @Transactional
    public Organ add(OrganVO organVO){
        //验证必填信息
        this.validate(organVO);
        Organ parentOrgan=organDao.findById(organVO.getParentId());
        if(Validator.isNull(parentOrgan)){
            throw ServiceException.create(OrganMsgCode.ORGAN_PARENT_NOT_EXIST);
        }
        //验证父级节点是否允许
        if(parentOrgan.getLevel()<Constants.ORGAN_LEVEL.ALLOWED_LEVEL){
            throw ServiceException.create(OrganMsgCode.ORGAN_PARENT_NOT_ALLOWED);
        }

        //验证是否为行政区域
        if(organVO.getType().equals(Constants.ORGAN_TYPE_STRING.PRIVINCE)){
            throw ServiceException.create(OrganMsgCode.ORGAN_CAN_NOT_ADD);
        }

        //查询父节点下是否已存在该名称的组织机构
        OrganVO organVO1=new OrganVO();
        organVO1.setName(organVO.getName());
        organVO1.setParentId(organVO.getParentId());
        OrganVO existOrgan=organDao.search(organVO1);
        if(Validator.isNotNull(existOrgan)){
            throw ServiceException.create(OrganMsgCode.ORGAN_EXIST);
        }


        this.validateCompany(organVO);
        Organ organ=new Organ();
        organVO.setLevel(parentOrgan.getLevel()+1);
        BeanUtils.copyProperties(organVO,organ);
        organDao.inser(organ);

        return organ;
    }

    public void validateCompany(OrganVO organVO){
        if(!Constants.ORGAN_TYPE_STRING.COMPANY.equals(organVO.getType())){
            return;
        }else {
            if(Validator.isNotNull(organVO.getCompanyId())) {
                Company company = companyDao.findById(organVO.getCompanyId());
                if(Validator.isNotNull(company)){//若选择了公司，则同步修改公司表中的信息
                  this.updateCompany(organVO);
                }
            }else {//若未选择公司，则在公司表新增数据
                Company company=new Company();
                company.setCompany(organVO.getName());
                company.setContactName(organVO.getContactName());
                company.setAddress(organVO.getAddress());

                Company company1=companyDao.findByname(company);
                if(Validator.isNotNull(company1)){
                    throw ServiceException.create(OrganMsgCode.COMPANY_EXIST);
                }
                companyDao.insert(company);
                organVO.setCompanyId(company.getId());
            }
        }
    }

    public  void updateCompany(OrganVO organVO){
        Company company = companyDao.findById(organVO.getCompanyId());
        if(Validator.isNotNull(company)) {//若选择了公司，则同步修改公司表中的信息
            if (Validator.isNull(organVO.getName())) {
                throw ServiceException.create(OrganMsgCode.ORGAN_NAME_IS_NULL);
            }
            if (Validator.isNull(organVO.getContactName())) {
                throw ServiceException.create(OrganMsgCode.ORGAN_CONTRACT_IS_NULL);
            }
            if (Validator.isNull(organVO.getPhone())) {
                throw ServiceException.create(OrganMsgCode.ORGAN_PHONE_IS_NULL);
            }
            company.setCompany(organVO.getName());
            company.setPhone(organVO.getPhone());
            company.setContactName(organVO.getContactName());
            company.setAddress(organVO.getAddress());
            companyDao.update(company);
            return;
        }
    }

    public void validate(OrganVO organVO){
        if(Validator.isNull(organVO)){
            throw ServiceException.create(OrganMsgCode.ORGAN_ADD_IS_NULL);
        }
        if(Validator.isNull(organVO.getParentId())){
            throw ServiceException.create(OrganMsgCode.ORGAN_PARENTID_IS_NULL);
        }
        if(Validator.isNull(organVO.getName())){
            throw ServiceException.create(OrganMsgCode.ORGAN_NAME_IS_NULL);
        }
        if(Validator.isNull(organVO.getContactName())){
            throw ServiceException.create(OrganMsgCode.ORGAN_CONTRACT_IS_NULL);
        }
        if(Validator.isNull(organVO.getPhone())){
            throw ServiceException.create(OrganMsgCode.ORGAN_PHONE_IS_NULL);
        }
        if(Validator.isNull(organVO.getType())){
            throw ServiceException.create(OrganMsgCode.ORGAN_TYPE_IS_NULL);
        }
        if(Validator.isNull(organVO.getAddress())){
            throw ServiceException.create(OrganMsgCode.ORGAN_ADDRESS_IS_NULL);
        }
    }


    /**
     *
     * 功能描述: 查找节点下的所有公司，除去节点的直接子节点
     *
     * @param:
     * @return:
     */
    public List<Company> findCompanyByParent(OrganVO organ){
        List<OrganVO> organVOS=organDao.findChildByParent(organ);
        if(Validator.isNull(organVOS)){
            return null;
        }
        organVOS.forEach(organVO -> {
            this.findChildList(organVO,organVOS);
        });

        List<Long> companyIds=organVOS.parallelStream().filter(organVO ->
                organ.getParentId()!=organ.getId()).filter(organVO ->
                Constants.ORGAN_TYPE_STRING.COMPANY.equals(organVO.getType()))
                .map(OrganVO::getCompanyId).collect(Collectors.toList());

        List<Company> companies=companyDao.searchList(companyIds);
        return companies;
    }

    /**
     *
     * 功能描述: 分页查询机构及子机构 不需要查出作业区域和中转站
     *
     * @param:
     * @return:
     */
    public PageInfo<OrganVO> findChildListByParent(OrganVO organVO){

        if(Validator.isNull(organVO)){
            return null;
        }

        Organ organ=organDao.findById(organVO.getId());
        BeanUtils.copyProperties(organ,organVO);

        Organ parentOrgan=organDao.findById(organVO.getParentId());
        if(Validator.isNull(parentOrgan)){
            throw ServiceException.create(OrganMsgCode.ORGAN_PARENT_NOT_EXIST);
        }
        organVO.setParentOrganName(parentOrgan.getName());

        List<OrganVO> orderList=new ArrayList<>();
        orderList.add(organVO);

        //查看该机构下是否有子机构
        List<OrganVO> childList=organDao.findChildByParent(organVO);

        //没有子机构直接返回
        if(Validator.isNull(childList)||Validator.isEmpty(childList)){
            PageInfo<OrganVO> pageInfo=new PageInfo<>(orderList);
            return pageInfo;
        }
        childList.forEach(organVO1 -> {
            organVO1.setParentOrganName(organVO.getName());
            this.findChildList(organVO1,orderList);
        });
        PageInfo<OrganVO> pageInfo=new PageInfo<>(orderList);
        return pageInfo;
    }

    public List<OrganVO> findChildList(OrganVO organVO,List<OrganVO> organVOS){
        if(Validator.isNull(organVO)){
            return organVOS;
        }
        organVOS.add(organVO);
        List<OrganVO> childList=organDao.findChildByParent(organVO);

        if(Validator.isNull(childList)||Validator.isEmpty(childList)){
            return organVOS;
        }
        childList.forEach(organVO1 -> {
            organVO1.setParentOrganName(organVO.getName());
            this.findChildList(organVO1,organVOS);
        });
        return organVOS;
    }

    /**
     *
     * 功能描述: 查出父级下的直接子集
     *
     * @param:
     * @return:
     */
    public  List<OrganVO> findOrganList(OrganVO organVO){
        if(Validator.isNull(organVO)){
            return null;
        }

        List<OrganVO> orderList=new ArrayList<>();
        orderList.add(organVO);

        //查看该机构下是否有子机构
        List<OrganVO> childList=organDao.findChildByParent(organVO);
        //TODO 查看组织机构下是否还有作业区域和中转站

        if(Validator.isNull(childList)||Validator.isEmpty(childList)){
            return orderList;
        }

        childList.forEach(organVO1 -> orderList.add(organVO1));
        return orderList;
    }

    /**
     *
     * 功能描述:根据当前登录用户查出组织机构树
     *
     * @param:
     * @return:
     */
    public List<OrganTree>  getOrganTree(){
        Long organId=userService.currentUser().getOrganId();
        List<OrganTree> organVOS= organDao.findChildTree(organId);
        List<OrganTree> organVOList=new ArrayList<>();
        OrganVO parentIdOrgan=organDao.findParentById(organId);
        if(Validator.isNotNull(parentIdOrgan)&&Validator.isNotNull(parentIdOrgan.getParentIds())){
            String[] parentIds=parentIdOrgan.getParentIds().split(",");
            for (int i = parentIds.length-1; i >0; i--) {
                if(Validator.isNotNull(parentIds[i])) {
                    Organ organ = organDao.findById(Long.parseLong(parentIds[i]));
                    OrganTree organVO = new OrganTree();
                    BeanUtils.copyProperties(organ,organVO);
                    organVOList.add(organVO);
                }
            }
        }
        if(Validator.isNotNull(organVOS)){
            organVOS.forEach(organVO -> organVOList.add(organVO));
        }

        //转化成树
        Map<Long,OrganTree> sortMap=new HashMap<>();
        for (OrganTree organVO:organVOList){
            OrganTree sortOrganVO = sortMap.get(organVO.getId());
            if (Validator.isNull(sortOrganVO)) {
                sortMap.put(organVO.getId(), organVO);
                organVO.setSubList(Lists.newArrayList());
            }
            if (Validator.isNotNull(organVO.getParentId())) {
                OrganTree parentOrganVo = sortMap.get(organVO.getParentId());
                if (Validator.isNotNull(parentOrganVo)) {
                    parentOrganVo.getSubList().add(organVO);
                }
            }
        }
        List<OrganTree> voList=organVOList.parallelStream().filter(organVO -> Constants.ORGAN_LEVEL.TOP_LEVEL==organVO.getLevel()).collect(Collectors.toList());
        return voList;
    }

    @Transactional
    public OrganVO modify(OrganVO organVO){
        if (Validator.isNull(organVO)||Validator.isNull(organVO.getAddress())
                ||Validator.isNull(organVO.getPhone())
                ||Validator.isNull(organVO.getContactName())){
            throw ServiceException.create(OrganMsgCode.ORGAN_NESSARY_IS_NULL);
        }
        if(organVO.getLevel()<=Constants.ORGAN_LEVEL.ALLOWED_LEVEL){
            throw ServiceException.create(OrganMsgCode.ORGAN_NOT_ALLOWED_MODIFY);
        }
        //查询父节点下是否已存在该名称的组织机构
        OrganVO organVO1=new OrganVO();
        organVO1.setName(organVO.getName());
        organVO1.setParentId(organVO.getParentId());
        OrganVO existOrgan=organDao.search(organVO1);
        if(Validator.isNotNull(existOrgan)){
            throw ServiceException.create(OrganMsgCode.ORGAN_EXIST);
        }

         organDao.modify(organVO);
        this.updateCompany(organVO);

        return organVO;
    }

    public void delete(Long id){
        Organ organ=organDao.findById(id);
        OrganVO organVO=new OrganVO();
        BeanUtils.copyProperties(organ,organ);
        //查看该机构下是否有子机构
        List<OrganVO> childList=organDao.findChildByParent(organVO);
        //TODO 查看组织机构下是否还有作业区域和中转站

        //有子机构不允许删除
        if(Validator.isNotNull(childList)||Validator.isNotEmpty(childList)){
            throw ServiceException.create(OrganMsgCode.ORGAN_HAS_CHILD);
        }

        organDao.delete(id);
    }

    /**
     *
     * 功能描述: 根据名字或者id查出对应机构
     *
     * @param: 机构名称或者id
     * @return:
     */
    public OrganVO findByNameOrId(OrganVO organVO) {
        if (Validator.isNull(organVO) ||
                Validator.isNull(organVO.getName()) && Validator.isNull(organVO.getId())) {
            return null;
        }
        OrganVO organVO1= organDao.findByIdOrName(organVO);
        return organVO1;
     }

     /**
      *
      * 功能描述: 根据机构名称列表查找机构
      *
      * @param:
      * @return:
      */
     public OrganVO findOrganByNames(List<String> organNames){
         OrganVO parentOrgan=new OrganVO();
         OrganVO organVO = new OrganVO();
         for (int i = 0; i <organNames.size() ; i++) {
             organVO.setName(organNames.get(i));
             organVO.setLevel(i);
             if(i==0){
                 parentOrgan=organDao.findForImport(organVO);
             }else {
                 if(Validator.isNull(parentOrgan)){
                     return null;
                 }
                 organVO.setParentId(parentOrgan.getId());
                 parentOrgan=organDao.findForImport(organVO);
             }
         }
         return parentOrgan;
     }

    }

